package MONITORING::HTTP::E2E;

#################################################################
# $LastChangedDate: 2013-11-25 15:03:06 +0000 (Mon, 25 Nov 2013) $
# $LastChangedRevision: 22 $
# $LastChangedBy: aswod_83@gmx.net $
#################################################################
use strict;
use base qw(moniCA);
use XML::Simple;
use Getopt::Long;
use Data::Dumper;
use Params::Validate qw(:all);
use WWW::Mechanize;

#-------------------------------------------------------------------------------
sub Run {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self   = shift;
    my $cnf    = $self->GetCNF();
    my $logger = $self->GetLogger();

    #-------------------------------------
    #	validation of default parameters
    #-------------------------------------
    $self->_validCNFdefaults( $cnf->{defaults} );

    #-------------------------------------
    #	validation of identifier parameters
    #-------------------------------------
    $self->_validCNFidentifierAll();

    #-------------------------------------
    #	pass through configured identifier
    #-------------------------------------
    foreach ( sort keys %{ $cnf->{identifier} } ) {

        $self->{ID} = $_;
        ( my $ident = $_ ) =~ s/\W/_/g;
        my %tmpstat;
        my %newstat;
        my $request;
        my $response;
        my $trigger =
          $self->{IdCfg}->{$_}->{'trigger'} || $self->{DefCfg}->{'triggerCnt'};
        my $report =
          $self->{IdCfg}->{$_}->{'report'} || $self->{DefCfg}->{'reporting'};
        my $statefile =
          $self->TmpDir() . '/' . $self->Plug() . '_' . $ident . '.xml';
        my $oldstat = XMLin($statefile)->{identifier}->{$_}
          if ( -s $statefile );

        #################

        my $ua = WWW::Mechanize->new();
        $ua->show_progress('TRUE') if ( $cnf->{LogLevel} eq 'DEBUG' );
        $ua->timeout( $self->{IdCfg}->{$_}->{'HttpTimeout'} )
          if ( $self->{IdCfg}->{$_}->{'HttpTimeout'} );

        $ua->get( $self->{IdCfg}->{$_}->{'HttpUrl'} );
        $ua->submit_form(
            with_fields => {
                $self->{IdCfg}->{$_}->{'PassField'} =>
                  $self->{IdCfg}->{$_}->{'ApplUserPass'},
                $self->{IdCfg}->{$_}->{'UserField'} =>
                  $self->{IdCfg}->{$_}->{'ApplUserName'}
            },
            button => 'login'
        );

        $logger->info( $ua->status );
        $ua->credentials(
            $self->{IdCfg}->{$_}->{'BasicAuthUser'},
            $self->{IdCfg}->{$_}->{'BasicAuthPassword'}
        ) if ( $self->{IdCfg}->{$_}->{'BasicAuthUser'} );

        $ua->reload();

        $self->{HttpResponse} = $ua->res();
        if ( $self->{HttpResponse}->content !~
            qr/$self->{IdCfg}->{$_}->{SuccessContent}/i )
        {
            $logger->error("login failed");
        }
        else {
            $logger->info("login successful");
        }

    }
}

#-------------------------------------------------------------------------------
sub _crReport {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------

    my $self   = shift;
    my $logger = $self->GetLogger();

    eval {
        require RRDs;

        ( my $rrdident = $self->{ID} ) =~ s/\W/_/g;

        my $rrdfile =
            $self->{RRDCfg}->{RRDFilePath} . '/'
          . $self->Plug() . '_'
          . $rrdident . '.rrd'
          if ( -d $self->{RRDCfg}->{rrdfilepath} ) || die($!);
        my $rrdimg =
            $self->{RRDCfg}->{RRDImagePath} . '/'
          . $self->Plug() . '_'
          . $rrdident . '.png'
          if ( -d $self->{RRDCfg}->{rrdimgpath} ) || die($!);

        if ( !-f $rrdfile ) {
            my @rrdc;
            push( @rrdc, "$rrdfile" );
            push( @rrdc, "--step=$self->{RRDCfg}->{step}" );
            if ( ref( $self->{RRDCfg}->{DS} ) eq "ARRAY" ) {
                for ( @{ $self->{RRDCfg}->{DS} } ) { push( @rrdc, $_ ); }
            }
            else {
                push( @rrdc, $self->{RRDCfg}->{DS} );
            }
            for ( @{ $self->{RRDCfg}->{RRA} } ) { push( @rrdc, $_ ); }

            RRDs::create(@rrdc);

            $logger->warn( "RRDs::create returns " . RRDs::error() )
              if ( RRDs::error() );
        }

        my @identlist;
        if ( ref( $self->{RRDCfg}->{DS} ) eq "ARRAY" ) {
            for ( @{ $self->{RRDCfg}->{DS} } ) {
                my @tmplist = split( /:/, $_ );
                push( @identlist, $tmplist[1] );
            }
        }
        else {
            my @tmplist = split( /:/, $self->{RRDCfg}->{DS} );
            push( @identlist, $tmplist[1] );
        }
        my $dslist = join( ":", @identlist );

        if ( -f $rrdfile ) {
            my @rrdu;
            my @dsvalue;
            for (@identlist) {
                push( @dsvalue, $self->{identifier}->{ $self->{ID} }->{$_} );
            }
            my $dsvalue = join( ":", @dsvalue );

            push( @rrdu, "$rrdfile" );
            push( @rrdu, "--template=$dslist" );
            push( @rrdu, "N:$dsvalue" );

            RRDs::update(@rrdu);

            $logger->warn( "RRDs::update returns " . RRDs::error() )
              if ( RRDs::error() );

            my @rrdg;
            $rrdfile =~ s/\:\//\\\:\//g if ( $^O eq 'MSWin32' );

            push( @rrdg, "$rrdimg" );
            push( @rrdg, "--title=$self->{RRDCfg}->{'title'}: $self->{ID}" );
            push( @rrdg, "--start=$self->{RRDCfg}->{'start'}" );
            push( @rrdg, "--end=$self->{RRDCfg}->{'end'}" );
            push( @rrdg, "--vertical-label=$self->{RRDCfg}->{'label'}" );
            push( @rrdg, "--imgformat=$self->{RRDCfg}->{'imgformat'}" );
            push( @rrdg, "--watermark=$self->{RRDCfg}->{'watermark'}" );
            push( @rrdg, "--width=$self->{RRDCfg}->{'width'}" );
            push( @rrdg, "--height=$self->{RRDCfg}->{'height'}" );

            foreach ( keys %{ $self->{RRDCfg}->{DEF} } ) {
                push( @rrdg,
                    "DEF:$_=$rrdfile:$_:$self->{RRDCfg}->{DEF}->{$_}->{CF}" );
                push( @rrdg,
"$self->{RRDCfg}->{DEF}->{$_}->{TYPE}:$_#$self->{RRDCfg}->{DEF}->{$_}->{COLOR}:$_ $self->{RRDCfg}->{DEF}->{$_}->{CF}"
                );
            }

            RRDs::graph(@rrdg);

            $logger->warn( "RRDs::graph returns " . RRDs::error() )
              if ( RRDs::error() );
        }
        1;
    } or $logger->debug( "Report incomplete: " . $@ );

}

#-------------------------------------------------------------------------------
sub _validCNFrrd {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;

    Params::Validate::validation_options( allow_extra => 1 );
    $self->{RRDCfg} = validate(
        @_,
        {
            rrdfilepath => {
                type     => SCALAR,
                default  => $self->VarDir(),
                optional => 1,
                regex    => qr/^.+$/
            },
            rrdimgpath => {
                type     => SCALAR,
                default  => $self->VarDir() . "/images",
                optional => 1,
                regex    => qr/^.+$/
            },
            title  => { type => SCALAR },
            label  => { type => SCALAR },
            width  => { type => SCALAR, default => "400", regex => qr/\d\d\d/ },
            height => { type => SCALAR, default => "100", regex => qr/\d\d\d/ },
            start     => { type => SCALAR, default => "end-24hours" },
            end       => { type => SCALAR, default => "now" },
            imgformat => { type => SCALAR, regex   => qr/[PNG||GIF||PDF]/ },
            watermark => {
                type    => SCALAR,
                default => "powered by andre.schmitt\@t-systems.com"
            },
            DS  => { type => ARRAYREF | SCALAR },
            RRA => { type => ARRAYREF | SCALAR }
        }
    );
    return $self;

}

#-------------------------------------------------------------------------------
sub _validCNFidentifier {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;

    Params::Validate::validation_options( allow_extra => 1 );
    $self->{IdCfg}->{ $self->{ID} } = validate(
        @_,
        {
            HttpUrl     => { type => SCALAR, regex   => qr/^.+$/ },
            HttpTimeout => { type => SCALAR, default => 10, optional => 1 },
            BasicAuthUser =>
              { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            BasicAuthPassword =>
              { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            ApplUserName =>
              { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            ApplUserPass =>
              { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            UserField => { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            PassField => { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            ContentSearch =>
              { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            SuccessContent =>
              { type => SCALAR, regex => qr/^.+$/, optional => 1 },
            reporting =>
              { type => SCALAR, regex => qr/^(on||off)$/i, optional => 1 },
            triggerCnt => { type => SCALAR, regex => qr/^.+$/, optional => 1 }
        }
    );
    return $self;
}

#-------------------------------------------------------------------------------
sub _validCNFidentifierAll {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;
    my $cnf  = $self->GetCNF();
    foreach ( keys %{ $cnf->{identifier} } ) {
        $self->{ID} = $_;
        $self->_validCNFidentifier( $cnf->{identifier}->{$_} );
    }
}

#-------------------------------------------------------------------------------
sub _validCNFdefaults {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;

    Params::Validate::validation_options( allow_extra => 0 );
    $self->{DefCfg} = validate(
        @_,
        {
            HttpTimeout => { type => SCALAR, default => 10 },
            reporting =>
              { type => SCALAR, regex => qr/^(on||off)$/i, optional => 1 },
            triggerCnt => { type => SCALAR, regex => qr/^.+$/, optional => 1 }
        }
    );
    return $self;
}

1;
__END__
 
=pod
 
=head1 NAME
 
E2E.pm - monitors website login
 
=head1 SYNOPSIS

=head1 OPTIONS

=head1 DESCRIPTION

=head1 PREREQUISITES
 
L<Log::Log4perl>,L<XML::Simple>,L<WW::Mechanize>

=head1 CONFIGURATION SAMPLE
 
 Modul 	    MONITORING::HTTP::E2E
 Logger		moniCA
 LogLevel	DEBUG
 Subject		moniCA E2E / ${APPL_NAME} / ${APPL_LAYER} / ${HOSTNAME}
 Description	This moniCA plug checks ...

 #DOC: 
 #DOC: 
 #DOC: 

 <defaults>
         report      = on
         trigger     = 2
         HttpTimeout = 1
 </defaults>

 #DOC:
 #DOC:
 #DOC:

 <identifier "tsitbs.telekom.de">
         HttpUrl           = https://tsitbs.telekom.de
         HttpTimeout       = 1
 #	     BasicAuthUser     =
 #   	 BasicAuthPassword =
         ContentSearch     = AN-TK Produktion
         UserField         = username
         PassField         = userpass
		 ApplUserPass      = start123
		 ApplUserName      = aschmit3
		 SuccessContent    = erfolgreich angemeldet
 </identifier>

 #DOC: 
 #DOC: 
 #DOC: 

 <rrd>
         #rrdimgpath  =
         #rrdfilepath =
         step         = 300
         DS           = DS:responsetime:GAUGE:600:0:100
         RRA          = RRA:AVERAGE:0.5:1:800
         RRA          =	RRA:AVERAGE:0.5:6:800
         RRA          = RRA:AVERAGE:0.5:24:800
         RRA          = RRA:AVERAGE:0.5:288:800
         title        = Endpoint
         label        = Response Time in sec 
         width        = 400
         height       = 100
         start        = end-24hours
         end          = now
         watermark    = powered by SAM
         imgformat    = PNG
         <DEF "responsetime">
                 CF    = AVERAGE
                 TYPE  = LINE2
                 COLOR = FFC0CB
         </DEF>
 </rrd>

=cut
